#include <iostream>
#include "hr_time.h"
#include <vector>
#include <iomanip>

using namespace std;

struct measurement
{
	int n;
	double time;
};

unsigned long long rFak(unsigned long long n)
{
	if (n == 0)
	{
		return 1;
	}
	else
	{
		return n * rFak(n - 1);
	}
}

unsigned long long iFak(unsigned long long n)
{
	unsigned long long i = 1;
	for (unsigned long long j = 1; j <= n; j++)
	{
		i *= j;
	}
	return i;
}

void main_testing()
{
	if (SetPriorityClass(GetCurrentProcess(), REALTIME_PRIORITY_CLASS) == 0)
	{
		std::cout << "Error: SetPriorityClass: " << GetLastError() << endl;
	}
	if (SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_TIME_CRITICAL) == 0)
	{
		std::cout << "Error: SetThreadPriority" << endl;
	}

	const int MAX = 9; 
	const int DELTA = 1; 
	const int nLoop = 100; 

	vector<measurement> rTime, iTime;
	CStopWatch w;
	double t0, t1;

	w.startTimer();
	rTime.clear();
	iTime.clear();
	std::cout.precision(8);
	std::cout.setf(ios::fixed);
	for (int n = DELTA; n < MAX; n += DELTA)
	{
		w.startTimer();
		for (int i = 0; i<nLoop; i++)
		{
			;
		}
		w.stopTimer();
		t0 = 1e6*w.getElapsedTime();

		w.startTimer();
		for (int i = 0; i < nLoop; i++)
		{
			volatile unsigned long long fak = rFak(n);
		}
		w.stopTimer();
		t1 = 1e6*w.getElapsedTime();
		double time1 = (t1 - t0) / (double)nLoop;
		measurement m1 = { n, time1 };
		rTime.push_back(m1);

		w.startTimer();
		for (int i = 0; i < nLoop; i++)
		{
			volatile unsigned long long fak = iFak(n);
		}
		w.stopTimer();
		t1 = 1e6*w.getElapsedTime();
		double time2 = (t1 - t0) / (double)nLoop;

		measurement m2 = { n, time2 };
		iTime.push_back(m2);
	}

	cout << "Rekursiv: " << endl;
	for (auto i : rTime)
	{
		cout << i.n << ": " << i.time << endl;
	}

	cout << "Iterativ: " << endl;
	for (auto i : iTime)
	{
		cout << i.n << ": " << i.time << endl;
	}
}

int main()
{
	main_testing();

	//iFak(5);

	system("pause");
	return 0;
}